/**
 * Copyright ®2015 sinosoft Co. Ltd. All rights reserved. 
 */
package com.sinosoft.platform.common.util;

import org.apache.commons.validator.GenericValidator;

/**
 * 验证工具类
 * @date 2010-11-25
 * @since JDK 1.5
 * @author dingkui
 * @version 1.0
 * 
 */
public class ValidateUtil extends GenericValidator {

    /**
     * serialVersionUID
     */
    private static final long serialVersionUID = 2350196588312183462L;

    /**
     * 判断字符串非空 字符串为null或""的时候返回false，否则为true
     * 
     * @param value
     *            待校验字符串
     * @return true/false
     */
    public static boolean isNotNullOrEmpty(String value) {
        return !GenericValidator.isBlankOrNull(value);
    }

    /**
     * 判断字符串是否合法的邮件地址 合法，则返回true
     * 
     * @param email
     *            邮件地址
     * @return true/false
     */
    public static boolean isEmail(String email) {
        return GenericValidator.isEmail(email);
    }

    /**
     * 验证邮编是否有效 有效返回true
     * 
     * @param zip
     *            邮编
     * @return true/false
     */
    public static boolean isZipValid(String zip) {
        boolean retval = false;
        if (null != zip) {
            String zipCodePattern = "\\d{5}(-\\d{4})?";
            String zipCodePattern1 = "\\d{6}";
            retval = zip.matches(zipCodePattern) || zip.matches(zipCodePattern1);
        }
        return retval;
    }

    /**
     * 
     * 方法功能描述
     * 
     * @param alui
     *            参数
     */
    public static void main(String[] alui) {
        System.out.println(isZipValid("76552"));
    }

    /**
     * 固定值判断 value同standard一致，则返回ture
     * 
     * @param value
     *            输入String
     * @param standard
     *            标准值
     * @return true/false
     */
    public static boolean validatorEqualEVoiceValue(String value, String standard) {
        if (null == value && null == standard) {
            return true;
        }
        else if (null == value || null == standard) {
            return false;
        }
        else {
            return value.equals(standard);
        }
    }

    /**
     * 验证字符串长度 value的长度为len，返回true
     * 
     * @param value
     *            字符串
     * @param len
     *            指定长度
     * @return true/false
     */
    public static boolean validatorLength(String value, int len) {
        return value.length() == len;
    }

    /**
     * 验证字符串是否由字母和数字组成 全由字母和数字，则返回true
     * 
     * @param str
     *            验证字符串
     * @return true/false
     */
    public static boolean validatorStringIsNumOrLetter(String str) {
        int j = 0;
        for (int i = 0; i < str.length(); i++) {
            if ((str.charAt(i) >= '0' && str.charAt(i) <= '9') || (str.charAt(i) >= 'a' && str.charAt(i) <= 'z')
                    || (str.charAt(i) >= 'A' && str.charAt(i) <= 'Z')) {
                j = j + 1;
            }
        }
        // 格式正确
        if (j == str.length()) {
            return true;
        }
        // 格式不对
        else {
            return false;
        }
    }

    /**
     * 验证证件号、证件类型、性别和生日是否正确 验证正确，返回true
     * 
     * @param idno
     *            证件号码
     * @param idtype
     *            证件类型
     * @param sex
     *            性别
     * @param birthday
     *            生日
     * @return boolean true/false
     */
    public static boolean checkIdCardWithSexAndBirthday(String idno, String idtype, String sex, String birthday) {
        // throws Exception

        // 如果证件类型为身份证
        if (idtype != null && idtype.trim().equals("0")) {
            String tmpbirthday = "";
            String tmpsex = "";
            // 截取身份证中的性别码和生日码
            if (idno.trim().length() == 18) {
                tmpbirthday = idno.substring(6, 14);
                tmpsex = idno.substring(16, 17);
            }
            else if (idno.trim().length() == 15) {
                tmpbirthday = idno.substring(6, 12);
                tmpbirthday = "19" + tmpbirthday;
                tmpsex = idno.substring(14, 15);
            }
            else {
                return false;
            }
            if (birthday == null || birthday.equals("")) {
                return false;
            }
            if (birthday.compareTo(tmpbirthday) != 0) {
                return false;
            }
            if (tmpsex.equals("0") || tmpsex.equals("2") || tmpsex.equals("4") || tmpsex.equals("6")
                    || tmpsex.equals("8")) {
                if (sex == null || sex.trim().equals("0")) {
                    return false;
                }
            }
            else {
                if (sex == null || sex.trim().equals("1")) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 验证身份证长度 长度为15或18位，则返回true
     * 
     * @param idno
     *            身份证号码
     * @return true/false
     */
    public static boolean checkIdCardLength(String idno) {
        if (idno.trim().length() == 18) {
            return true;
        }
        else if (idno.trim().length() == 15) {
            return true;
        }
        else {
            return false;
        }
    }

    /**
     * 验证身份证与性别组合是否正确 正确，则返回true
     * 
     * @param idno
     *            身份证号
     * @param sex
     *            性别
     * @return true/false
     */
    public static boolean checkIdCardWithSex(String idno, String sex) {
        String tmpsex = "";
        if (idno.trim().length() == 18) {
            tmpsex = idno.substring(16, 17);
        }
        else if (idno.trim().length() == 15) {
            tmpsex = idno.substring(14, 15);
        }
        else {
            return false;
        }
        if (tmpsex.equals("0") || tmpsex.equals("2") || tmpsex.equals("4") || tmpsex.equals("6") || tmpsex.equals("8")) {
            if (sex == null || sex.trim().equals("0")) {
                return false;
            }
        }
        else {
            if (sex == null || sex.trim().equals("1")) {
                return false;
            }
        }
        return true;
    }

    /**
     * 验证身份证与出生日期组合正确 正确，则返回true
     * 
     * @param idno
     *            身份证号
     * @param birthday
     *            生日
     * @return true/false
     */
    public static boolean checkIdCardWithBirthday(String idno, String birthday) {
        String tmpbirthday = "";
        if (idno.trim().length() == 18) {
            tmpbirthday = idno.substring(6, 14);
        }
        else if (idno.trim().length() == 15) {
            tmpbirthday = idno.substring(6, 12);
            tmpbirthday = "19" + tmpbirthday;
        }
        else {
            return false;
        }
        if (birthday.compareTo(tmpbirthday) != 0) {
            return false;
        }
        return true;
    }

    /**
     * 严格校验身份证号码 身份证号码正确，返回true
     * 
     * @param idCard
     *            身份证号码
     * @return boolean true/false
     */
    public static boolean checkIdCard(String idCard) {
        String systemDate = DateUtil.getCurrentDate("yyyyMMdd");
        int year = Integer.parseInt(systemDate.substring(0, 4));
        int month = Integer.parseInt(systemDate.substring(4, 6)) + 1;
        int day = Integer.parseInt(systemDate.substring(6));
        int yyyy; // 年
        int mm; // 月
        int dd; // 日
        int id_length = idCard.length();
        if (id_length == 0) {
            return false;
        }
        if (id_length != 15 && id_length != 18) {
            return false;
        }
        if (id_length == 15) {
            char[] tCode = idCard.toUpperCase().toCharArray();
            int tASC;
            for (int i = 0; i < id_length; i++) {
                // 通过ASC码表进行识别
                tASC = (int) tCode[i];
                // 不属于数字的都是非法的 数字0-9的ASC码表位于48-57之间
                if (tASC < 48 || tASC > 57) {
                    return false;
                }
            }
            yyyy = Integer.parseInt("19" + idCard.substring(6, 8));
            mm = Integer.parseInt(idCard.substring(8, 10));
            dd = Integer.parseInt(idCard.substring(10, 12));
            if (mm > 12 || mm <= 0) {
                return false;
            }
            if (dd > 31 || dd <= 0) {
                return false;
            }
            // 4,6,9,11月份日期不能超过30
            if ((mm == 4 || mm == 6 || mm == 9 || mm == 11) && (dd > 30)) {
                return false;
            }
            // 判断2月份
            if (mm == 2) {
                if (DateUtil.isLeapYear(yyyy)) {
                    if (dd > 29) {
                        return false;
                    }
                }
                else {
                    if (dd > 28) {
                        return false;
                    }
                }
            }
        }
        else {
            char[] tCode = idCard.toUpperCase().toCharArray();
            int tASC;
            for (int i = 0; i < id_length - 1; i++) {
                // 通过ASC码表进行识别
                tASC = (int) tCode[i];
                // 不属于数字的都是非法的 数字0-9的ASC码表位于48-57之间
                if (tASC < 48 || tASC > 57) {
                    return false;
                }
            }
            tASC = (int) tCode[17];
            if (tASC < 48 || tASC > 57) {
                if (!idCard.substring(17).equals("X") && !idCard.substring(17).equals("x")) {
                    return false;
                }
            }
            if (idCard.indexOf("X") > 0 && idCard.indexOf("X") != 17 || idCard.indexOf("x") > 0
                    && idCard.indexOf("x") != 17) {
                return false;
            }
            yyyy = Integer.parseInt(idCard.substring(6, 10));
            if (yyyy > year || yyyy < 1900) {
                return false;
            }
            mm = Integer.parseInt(idCard.substring(10, 12));
            if (mm > 12 || mm <= 0) {
                return false;
            }
            if (yyyy == year && mm > month) {
                return false;
            }
            dd = Integer.parseInt(idCard.substring(12, 14));
            return false;
        }
        // 4,6,9,11月份日期不能超过30
        if ((mm == 4 || mm == 6 || mm == 9 || mm == 11) && (dd > 30)) {
            return false;
        }
        // 判断2月份
        if (mm == 2) {
            if (DateUtil.isLeapYear(yyyy)) {
                if (dd > 29) {
                    return false;

                }
            }
            else {
                if (dd > 28) {
                    return false;
                }
            }
        }
        if (yyyy == year && mm == month && dd > day) {
            return false;
        }
        if (idCard.substring(17).equals("x") || idCard.substring(17).equals("X")) {
            if (!GetVerifyBit(idCard).equals("x") && !GetVerifyBit(idCard).equals("X")) {
                return false;
            }
        }
        else {
            if (!idCard.substring(17).equals(GetVerifyBit(idCard))) {
                return false;

            }
        }
        return true;
    }

    /**
     * 计算身份证校验码 原理: ∑(a[i]*W[i]) mod 11 ( i = 2, 3, ..., 18) (1) "*" 表示乘号 i--------表示身份证号码每一位的序号，从右至左，最左侧为18，最右侧为1。
     * a[i]-----表示身份证号码第 i 位上的号码 W[i]-----表示第 i 位上的权值 W[i] = 2^(i-1) mod 11 计算公式 (1) 令结果为 R 根据下表找出 R
     * 对应的校验码即为要求身份证号码的校验码C。 R 0 1 2 3 4 5 6 7 8 9 10 C 1 0 X 9 8 7 6 5 4 3 2 X 就是 10，罗马数字中的 10 就是 X 15位转18位中,计算校验位即最后一位
     * 
     * @param id
     *            身份证号码
     * @return 校验码
     */
    public static String GetVerifyBit(String id) {
        String result = null;

        int nNum = Integer.parseInt(id.substring(0, 1)) * 7 + Integer.parseInt(id.substring(1, 2)) * 9
                + Integer.parseInt(id.substring(2, 3)) * 10 + Integer.parseInt(id.substring(3, 4)) * 5
                + Integer.parseInt(id.substring(4, 5)) * 8 + Integer.parseInt(id.substring(5, 6)) * 4
                + Integer.parseInt(id.substring(6, 7)) * 2 + Integer.parseInt(id.substring(7, 8)) * 1
                + Integer.parseInt(id.substring(8, 9)) * 6 + Integer.parseInt(id.substring(9, 10)) * 3
                + Integer.parseInt(id.substring(10, 11)) * 7 + Integer.parseInt(id.substring(11, 12)) * 9
                + Integer.parseInt(id.substring(12, 13)) * 10 + Integer.parseInt(id.substring(13, 14)) * 5
                + Integer.parseInt(id.substring(14, 15)) * 8 + Integer.parseInt(id.substring(15, 16)) * 4
                + Integer.parseInt(id.substring(16, 17)) * 2;
        nNum = nNum % 11;
        switch (nNum) {
        case 0:
            result = "1";
            break;
        case 1:
            result = "0";
            break;
        case 2:
            result = "X";
            break;
        case 3:
            result = "9";
            break;
        case 4:
            result = "8";
            break;
        case 5:
            result = "7";
            break;
        case 6:
            result = "6";
            break;
        case 7:
            result = "5";
            break;
        case 8:
            result = "4";
            break;
        case 9:
            result = "3";
            break;
        case 10:
            result = "2";
            break;
        }
        return result;
    }

    /**
     * 判断10位字符串是否是日期 例如：1983-16-35就不是日期
     * 
     * @param strNum
     *            待验证的字符串
     * @return true/false
     */
    public static boolean checkNum(String strNum) {
        if (strNum == null || strNum.equals("")) {
            return false;
        }
        int year = Integer.parseInt(strNum.substring(0, 4));
        int mon = Integer.parseInt(strNum.substring(5, 7));
        int day = Integer.parseInt(strNum.substring(8, 10));

        if (mon > 12 || mon < 1 || year < 1) {
            return false;
        }
        else {
            if (mon == 1 || mon == 3 || mon == 5 || mon == 7 || mon == 8 || mon == 10 || mon == 12) {
                if (day < 1 || day > 31) {
                    return false;
                }

            }
            if (mon == 4 || mon == 6 || mon == 9 || mon == 11) {
                if (day < 1 || day > 30) {
                    return false;
                }
            }
            if (mon == 2) {
                if (year % 400 == 0 | year % 100 != 0 & year % 4 == 0) {
                    if (day < 1 || day > 29) {
                        return false;
                    }
                }
                else {
                    if (day < 1 || day > 28) {
                        return false;
                    }
                }
            }
            return true;
        }
    }

    /**
     * 判断8位数是否是日期 例如：19831635就不是日期
     * 
     * @param strNum
     *            待验证的字符串
     * @return true/false
     */
    public static boolean checkNumStr(String strNum) {
        if (strNum == null || strNum.equals("") || strNum.length() != 8 || !GenericValidator.isInt(strNum)) {
            return false;
        }
        int year = Integer.parseInt(strNum.substring(0, 4));
        int mon = Integer.parseInt(strNum.substring(4, 6));
        int day = Integer.parseInt(strNum.substring(6, 8));

        if (mon > 12 || mon < 1 || year < 1) {
            return false;
        }
        else {
            if (mon == 1 || mon == 3 || mon == 5 || mon == 7 || mon == 8 || mon == 10 || mon == 12) {
                if (day < 1 || day > 31) {
                    return false;
                }

            }
            if (mon == 4 || mon == 6 || mon == 9 || mon == 11) {
                if (day < 1 || day > 30) {
                    return false;
                }
            }
            if (mon == 2) {
                if (year % 400 == 0 | year % 100 != 0 & year % 4 == 0) {
                    if (day < 1 || day > 29) {
                        return false;
                    }
                }
                else {
                    if (day < 1 || day > 28) {
                        return false;
                    }
                }
            }
            return true;
        }
    }

}
